//    Copyright (C) Kherty.  All rights reserved.
using System.Windows;
using System.Windows.Media;
using OpenLS.Drawing;


namespace OpenLS.Spreadsheet.UI
{
    class BorderDrawer
    {
        static internal void DrawLine(DrawingContext context, Pen pen, Point p1, Point p2)
        {
            double offset = pen.Thickness / 2 - (double)((int)(pen.Thickness / 2));

            context.DrawLine(pen, new Point((int)p1.X + offset, (int)p1.Y + offset), new Point((int)p2.X + offset, (int)p2.Y + offset));
        }
        enum Corner
        {
            TopLeft,
            TopRight,
            BottomLeft,
            BottomRight,
        }
        static void DrawDoubleLine(DrawingContext context, Pen pen, Point p1, Point p2, Corner o1, Corner o2
            , Corner o3, Corner o4)
        {
            Point pp1 = p1;
            Point pp2 = p2;
            OffsetCorner(ref pp1, o1);
            OffsetCorner(ref pp2, o2);
            DrawLine(context, pen, pp1, pp2);
            pp1 = p1;
            pp2 = p2;
            OffsetCorner(ref pp1, o3);
            OffsetCorner(ref pp2, o4);
            DrawLine(context, pen, pp1, pp2);
        }

        // ReSharper disable RefParameterCanBeMoreSpecific
        private static void OffsetCorner(ref Point p1, Corner o1)
        // ReSharper restore RefParameterCanBeMoreSpecific
        {
            switch (o1)
            {
                case Corner.TopLeft:
                    p1.Offset(-1, -1);
                    break;
                case Corner.TopRight:
                    p1.Offset(1, -1);
                    break;
                case Corner.BottomLeft:
                    p1.Offset(-1, 1);
                    break;
                case Corner.BottomRight:
                    p1.Offset(1, 1);
                    break;

            }
        }
        public delegate Pen PenGetter(Border border, ColorScheme colorScheme);

        public static void DrawBorders(DrawingContext drawingContext, Borders Borders, Rect rect, ColorScheme colorScheme,
                  PenGetter GetPen)
        {
            if (Borders == null)
                return;
            if (HasBorder(Borders.Left))
            {
                if (
                    Borders.Left.Style == BorderStyle.Double)
                {
                    DrawDoubleLine(drawingContext, GetPen(Borders.Left, colorScheme),
                        rect.TopLeft, rect.BottomLeft,
                                   Corner.TopLeft, Corner.BottomLeft,
                                   HasBorder(Borders.Top) ? Corner.BottomRight : Corner.TopRight, HasBorder(Borders.Bottom) ? Corner.TopRight : Corner.BottomRight);
                }
                else
                {
                    DrawLine(drawingContext, GetPen(Borders.Left, colorScheme), rect.TopLeft, rect.BottomLeft);
                }
            }
            if (HasBorder(Borders.Top))
            {
                if (Borders.Top.Style == BorderStyle.Double)
                {
                    DrawDoubleLine(drawingContext, GetPen(Borders.Top, colorScheme),
                                   rect.TopLeft, rect.TopRight,
                                   Corner.TopLeft, Corner.TopRight,
                                   HasBorder(Borders.Left) ? Corner.BottomRight : Corner.BottomLeft, HasBorder(Borders.Right) ? Corner.BottomLeft : Corner.BottomRight);
                }
                else
                {
                    DrawLine(drawingContext, GetPen(Borders.Top, colorScheme), rect.TopLeft, rect.TopRight);
                }
            }
            if (HasBorder(Borders.Right))
            {
                if (Borders.Right.Style == BorderStyle.Double)
                {
                    DrawDoubleLine(drawingContext, GetPen(Borders.Right, colorScheme),
                                   rect.TopRight, rect.BottomRight,
                                   Corner.TopRight, Corner.BottomRight,
                                   HasBorder(Borders.Top) ? Corner.BottomLeft : Corner.TopLeft, HasBorder(Borders.Bottom) ? Corner.TopLeft : Corner.BottomLeft);
                }
                else
                {
                    DrawLine(drawingContext, GetPen(Borders.Right, colorScheme), rect.TopRight, rect.BottomRight);
                }
            }
            if (HasBorder(Borders.Bottom))
            {
                if (Borders.Bottom.Style == BorderStyle.Double)
                {
                    DrawDoubleLine(drawingContext, GetPen(Borders.Bottom, colorScheme),
                                   rect.BottomLeft, rect.BottomRight,
                                   Corner.BottomLeft, Corner.BottomRight,
                                   HasBorder(Borders.Left) ? Corner.TopRight : Corner.TopLeft, HasBorder(Borders.Left) ? Corner.TopLeft : Corner.TopRight);
                }
                else
                {
                    DrawLine(drawingContext, GetPen(Borders.Bottom, colorScheme), rect.BottomLeft,
                             rect.BottomRight);
                }
            }
        }

        internal static bool HasBorder(Border border)
        {
            if (border == null)
                return false;
            if (border.Style == BorderStyle.None)
                return false;
            return true;
        }


    }
}
